﻿using System;
using System.Windows;
using System.Windows.Threading;
using OpenCL.Net;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using Microsoft.Win32;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading;
using System.Numerics;
using System.Linq;
using ClosedXML.Excel;

namespace GPUAPP2;



public class Metrics
{
    public long BatchesProcessed { get; set; }
    public long TotalRowsProcessed { get; set; }
    public double TotalTransformTime { get; set; }
    public double TotalProcessingTime { get; set; }
    public double TotalCountTime { get; set; }
}

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    private Context context;
    private CommandQueue queue;
    private Program program;
    private Kernel kernel;
    private bool isProcessing = false;
    private DispatcherTimer progressTimer;
    private Stopwatch stopwatch;
    private Device[] devices;
    private BigInteger totalProcessedRows = 0;
    private DataManager dataManager;
    private DataGenerator dataGenerator;
    private DataTransformer dataTransformer;
    private FDataDisplayManager fDataDisplayManager;
    private int[][] nData;
    private DataTransformer.TransformDataRow[] transformData;
    private ConcurrentQueue<int[][]> dataQueue = new ConcurrentQueue<int[][]>();
    private ConcurrentQueue<int[]> permutationQueue = new ConcurrentQueue<int[]>();
    private volatile bool isDataGenerationComplete = false;
    private volatile bool shouldStopProcessing = false;
    private AutoResetEvent dataAvailableEvent = new AutoResetEvent(false);
    private Metrics metrics = new Metrics();
    private int threshold;
    private int currentBatchSize = 10000; // 默认批次大小
    private bool countTransformHits = false; // 是否统计转换数据命中次数

    // OpenCL 相关成员
    private Mem transformDataBuffer;
    private Mem yDataBuffer;
    private Mem resultBuffer;
    private int[] gpuResults;
    private const int WORK_GROUP_SIZE = 256;

    public MainWindow()
    {
        //AllocConsole();
        InitializeComponent();
        InitializeTimer();
        InitializeOpenCL();
        dataManager = new DataManager();
        dataTransformer = new DataTransformer();
        fDataDisplayManager = new FDataDisplayManager(dgFData);
        CheckError();
    }

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AllocConsole();

    private void InitializeTimer()
    {
        progressTimer = new DispatcherTimer();
        progressTimer.Interval = TimeSpan.FromMilliseconds(100);
        progressTimer.Tick += ProgressTimer_Tick;
        stopwatch = new Stopwatch();
    }

    private void ProgressTimer_Tick(object sender, EventArgs e)
    {
        if (stopwatch.IsRunning)
        {
            double elapsedSeconds = stopwatch.Elapsed.TotalSeconds;
            if (elapsedSeconds > 0)
            {
                double rowsPerSecond = (double)totalProcessedRows / elapsedSeconds;
                double estimatedHourly = rowsPerSecond * 3600;
                
                txtStatus.Text = $"处理中... 已用时间: {elapsedSeconds:F2}秒";
                txtProcessSpeed.Text = $"处理速度: {rowsPerSecond:N0} 行/秒";
                txtEstimatedHourly.Text = $"预估每小时: {estimatedHourly / 100_000_000:F2} 亿行";
            }
        }
    }

    private void btnSelectFile_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            // 设置默认文件路径
            string defaultPath = @"E:\C#调用显卡计算\gpu-calc\ConsoleApp2\data\210行比较数【B表】据.txt";
            
            if (File.Exists(defaultPath))
            {
                LoadDataFile(defaultPath);
            }
            else
            {
                MessageBox.Show("默认文件不存在，请手动选择文件", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                
                var dialog = new OpenFileDialog
                {
                    Filter = "文本文件|*.txt|所有文件|*.*",
                    Title = "选择Y数据文件"
                };

                if (dialog.ShowDialog() == true)
                {
                    LoadDataFile(dialog.FileName);
                }
            }
        }
        catch (Exception ex)
        {
            LogMessage($"文件选择失败: {ex.Message}");
            MessageBox.Show($"文件选择失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void btnSelectTransformFile_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var dialog = new OpenFileDialog
            {
                Filter = "文本文件|*.txt|所有文件|*.*",
                Title = "选择转换前数据文件"
            };

            if (dialog.ShowDialog() == true)
            {
                LoadTransformFile(dialog.FileName);
            }
        }
        catch (Exception ex)
        {
            LogMessage($"转换前数据文件选择失败: {ex.Message}");
            MessageBox.Show($"转换前数据文件选择失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void LoadTransformFile(string filePath)
    {
        try
        {
            transformData = dataTransformer.LoadTransformData(filePath);
            txtTransformFilePath.Text = filePath;
            
            // 创建转换数据缓冲区
            int[] transformDataArray = new int[transformData.Length * 3];
            for (int i = 0; i < transformData.Length; i++)
            {
                transformDataArray[i * 3] = transformData[i].Value1;
                transformDataArray[i * 3 + 1] = transformData[i].Value2;
                transformDataArray[i * 3 + 2] = transformData[i].Value3;
            }

            ErrorCode error;
            transformDataBuffer = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly | MemFlags.CopyHostPtr, (IntPtr)(transformDataArray.Length * sizeof(int)), transformDataArray, out  error);
            
            // 在UI线程中更新DataGrid
            Application.Current.Dispatcher.Invoke(() =>
            {
                dgTransformData.ItemsSource = null;
                dgTransformData.ItemsSource = transformData;
                LogMessage($"成功加载转换前数据文件，共{transformData.Length}行数据");
            });
        }
        catch (Exception ex)
        {
            LogMessage($"加载转换前数据文件失败: {ex.Message}");
            MessageBox.Show($"加载转换前数据文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            txtTransformFilePath.Text = "未选择文件";
            dgTransformData.ItemsSource = null;
        }
    }

    private void LoadDataFile(string filePath)
    {
        try
        {
            if (dataManager.LoadData(filePath))
            {
                txtFilePath.Text = dataManager.FilePath;
                
                // 创建Y数据缓冲区
                int[] yDataArray = new int[dataManager.YDataRows.Count * 3];
                for (int i = 0; i < dataManager.YDataRows.Count; i++)
                {
                    yDataArray[i * 3] = dataManager.YDataRows[i].F0;
                    yDataArray[i * 3 + 1] = dataManager.YDataRows[i].F1;
                    yDataArray[i * 3 + 2] = dataManager.YDataRows[i].F2;
                }
                
                yDataBuffer = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly | MemFlags.CopyHostPtr, (IntPtr)(yDataArray.Length * sizeof(int)), yDataArray, out var error);
                if (error != ErrorCode.Success)
                    throw new Exception($"创建Y数据缓冲区失败: {error}");
                
                // 在UI线程中更新DataGrid
                Application.Current.Dispatcher.Invoke(() =>
                {
                    dgYData.ItemsSource = null;
                    dgYData.ItemsSource = dataManager.YDataRows;
                    LogMessage($"成功加载文件，共{dataManager.RowCount}行数据");
                    LogMessage($"数据示例: {dataManager.GetDataSample()}");
                });
            }
        }
        catch (Exception ex)
        {
            LogMessage($"加载文件失败: {ex.Message}");
            MessageBox.Show($"加载文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            txtFilePath.Text = "未选择文件";
            dgYData.ItemsSource = null;
        }
    }

    private void rbRandom_Checked(object sender, RoutedEventArgs e)
    {
        if(txtRowCount != null)
        txtRowCount.IsEnabled = true;
    }

    private void rbPermutation_Checked(object sender, RoutedEventArgs e)
    {
        if (txtRowCount != null)
            txtRowCount.IsEnabled = false;
    }

    private void rbImport_Checked(object sender, RoutedEventArgs e)
    {
        btnImportData.IsEnabled = true;
        txtRowCount.IsEnabled = false;
    }

    private void btnImportData_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var dialog = new OpenFileDialog
            {
                Filter = "文本文件|*.txt|所有文件|*.*",
                Title = "选择导入的阶乘数据文件"
            };

            if (dialog.ShowDialog() == true)
            {
                ImportDataFile(dialog.FileName);
            }
        }
        catch (Exception ex)
        {
            LogMessage($"导入数据文件失败: {ex.Message}");
            MessageBox.Show($"导入数据文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void ImportDataFile(string filePath)
    {
        try
        {
            // 读取文件内容
            string[] lines = File.ReadAllLines(filePath);
            List<int[]> importedData = new List<int[]>();

            // 解析每一行数据
            foreach (string line in lines)
            {
                string[] values = line.Split(',');
                if (values.Length != 30)
                {
                    throw new Exception($"数据格式错误：每行必须包含30个数字，当前行包含{values.Length}个数字");
                }

                int[] row = new int[30];
                for (int i = 0; i < 30; i++)
                {
                    if (!int.TryParse(values[i].Trim(), out row[i]))
                    {
                        throw new Exception($"数据格式错误：无法解析数字 '{values[i]}'");
                    }
                }
                importedData.Add(row);
            }

            // 将数据加入队列
            dataQueue.Enqueue(importedData.ToArray());
            isDataGenerationComplete = true;
            dataAvailableEvent.Set();

            LogMessage($"成功导入数据，共{importedData.Count}行");
            MessageBox.Show($"成功导入数据，共{importedData.Count}行", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
        }
        catch (Exception ex)
        {
            LogMessage($"导入数据失败: {ex.Message}");
            throw;
        }
    }

    private async void btnStart_Click(object sender, RoutedEventArgs e)
    {
        if (isProcessing)
        {
            MessageBox.Show("正在处理中，请等待...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
            return;
        }

        try
        {
            // 重置计数器和队列
            totalProcessedRows = 0;
            permutationQueue.Clear();
            dgResults.Items.Clear();
            txtProcessedRows.Text = "已处理行数: 0 / 0";
            txtMatchCount.Text = "匹配行数: 0";
            progressBar.Value = 0;

            // 重置转换数据的命中次数
            if (transformData != null)
            {
                foreach (var data in transformData)
                {
                    data.Count = 0;
                }
                dgTransformData.ItemsSource = null;
                dgTransformData.ItemsSource = transformData;
            }

            if (transformData == null || transformData.Length == 0)
            {
                MessageBox.Show("请先加载转换前数据文件", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            int seedStart=0, seedEnd=29;
            // 验证种子值
            if (rbRandom.IsChecked == true)
            {
                if (!int.TryParse(txtSeedStart.Text, out  seedStart))
                {
                    MessageBox.Show("请输入有效的起始种子值", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (!int.TryParse(txtSeedEnd.Text, out  seedEnd))
                {
                    MessageBox.Show("请输入有效的结束种子值", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (seedStart >= seedEnd)
                {
                    MessageBox.Show("起始种子值必须小于结束种子值", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            // 获取基准值
            if (!int.TryParse(txtThreshold.Text, out threshold))
            {
                MessageBox.Show("基准值无效", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // 读取是否统计转换数据命中次数
            countTransformHits = chkCountTransformHits.IsChecked == true;

            dataManager.ValidateData();

            // 初始化数据生成器
            if (rbRandom.IsChecked == true)
            {
                dataGenerator = new DataGenerator(seedStart, seedEnd);
            }
            else if (rbPermutation.IsChecked == true)
            {
                dataGenerator = new DataGenerator(0, 29);
            }
            // 导入数据模式不需要初始化dataGenerator

            isProcessing = true;
            shouldStopProcessing = false;
       
    

            btnStart.IsEnabled = false;
            btnSelectFile.IsEnabled = false;
            btnSelectTransformFile.IsEnabled = false;
            btnImportData.IsEnabled = false;
            progressBar.Value = 0;
            txtStatus.Text = "准备数据...";
            stopwatch.Restart();
            progressTimer.Start();

            permutationQueue.Clear();

            // 启动数据生成线程（如果不是导入数据模式）
            Task dataGenerationTask = Task.CompletedTask;
            if (rbImport.IsChecked != true)
            {
                dataQueue = new ConcurrentQueue<int[][]>();
                isDataGenerationComplete = false;
                dataGenerationTask = Task.Run(() => GenerateDataAsync());
            }

            // 启动数据处理线程
            var processingTask = Task.Run(() => ProcessData());

            // 等待任务完成
            await Task.WhenAll(dataGenerationTask, processingTask);

            stopwatch.Stop();
            progressTimer.Stop();
            txtStatus.Text = $"处理完成！总用时: {stopwatch.Elapsed.TotalSeconds:F2}秒";
            LogMessage($"处理完成！总用时: {stopwatch.Elapsed.TotalSeconds:F2}秒");
        }
        catch (Exception ex)
        {
            LogMessage($"处理失败: {ex.Message}");
            Console.WriteLine(ex.StackTrace);
            MessageBox.Show($"处理失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        finally
        {
            isProcessing = false;
            shouldStopProcessing = true;
            btnStart.IsEnabled = true;
            btnSelectFile.IsEnabled = true;
            btnSelectTransformFile.IsEnabled = true;
            btnImportData.IsEnabled = rbImport.IsChecked == true;
        }
    }

    private async Task GenerateDataAsync()
    {
        try
        {
            // 获取用户设置的批次大小
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                if (int.TryParse(txtBatchSize.Text, out int batchSize) && batchSize > 0)
                {
                    currentBatchSize = batchSize;
                }
            });

            const int PREVIEW_ROWS = 1000; // 预览的行数
            
            // 在UI线程中安全地获取所需的值
            bool isRandomMode = false;
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                isRandomMode = rbRandom.IsChecked ?? false;
            });
            
            long rowCount;
            if (isRandomMode)
            {
                // 随机生成模式：使用用户输入的行数
                double billionRows = 0;
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    billionRows = double.Parse(txtRowCount.Text);

                });
                rowCount = (long)(billionRows * 100000000);
            }
            else
            {
                // 全排列模式：使用30的阶乘
                rowCount = CalculateFactorial(30);
            }

            long processedRows = 0;
            var previewData = new List<int[]>(PREVIEW_ROWS);

            while (processedRows < rowCount && !shouldStopProcessing)
            {
                // 计算本批次要生成的行数
                int currentBatchSize = (int)Math.Min(this.currentBatchSize, rowCount - processedRows);

                // 生成一批数据
                int[][] batchData = isRandomMode
                    ? dataGenerator.GenerateRandomData(currentBatchSize)
                    : dataGenerator.GeneratePermutationData(currentBatchSize);

                // 收集预览数据
                if (processedRows < PREVIEW_ROWS)
                {
                    int remainingRows = PREVIEW_ROWS - previewData.Count;
                    if (remainingRows > 0)
                    {
                        var newPreviewData = batchData.Take(remainingRows).ToArray();
                        previewData.AddRange(newPreviewData);
                        fDataDisplayManager.UpdateDisplay(previewData);
                    }
                }

                // 将数据加入队列
                dataQueue.Enqueue(batchData);
                dataAvailableEvent.Set();

                processedRows += currentBatchSize;

                // 如果队列太大，等待消费者处理
                while (dataQueue.Count > 10 && !shouldStopProcessing)
                {
                    await Task.Delay(100);
                }

                // 更新进度
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    UpdateUI(processedRows, permutationQueue.Count);
                });
            }

            LogMessage($"数据生成完成，共生成 {processedRows:N0} 行数据");
            isDataGenerationComplete = true;
            dataAvailableEvent.Set();
        }
        catch (Exception ex)
        {
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                LogMessage($"数据生成失败: {ex.Message}");
            });
            shouldStopProcessing = true;
            throw;
        }
    }

    private long CalculateFactorial(int n)
    {
        if (n < 0) return 0;
        if (n == 0) return 1;
        
        BigInteger result = 1;
        for (int i = 1; i <= n; i++)
        {
            result *= i;
        }

        // 如果结果超过long.MaxValue，返回long.MaxValue
        if (result > long.MaxValue)
        {
            return long.MaxValue;
        }
        
        return (long)result;
    }

    private void ProcessData()
    {
        ErrorCode error;
        try
        {
            if (transformData == null || transformData.Length == 0)
            {
                throw new ArgumentException("转换前数据不能为空");
            }

            try
            {
                // 处理数据直到生成完成且队列为空
                while (!shouldStopProcessing && (!isDataGenerationComplete || !dataQueue.IsEmpty))
                {
                    int[][] batchData;
                    if (dataQueue.TryDequeue(out batchData))
                    {
                        // 直接处理生成的数据
                        ProcessBatch(batchData);
                        totalProcessedRows += batchData.Length;

                        // 更新UI（每100行更新一次）
                        if (totalProcessedRows % 100 == 0)
                        {
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                UpdateUI(totalProcessedRows, permutationQueue.Count);
                            });
                        }
                    }
                    else
                    {
                        // 等待新数据
                        dataAvailableEvent.WaitOne(100);
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            LogMessage($"生成阶乘数据...");
                        });
                    }
                }

                // 最终更新UI
                Application.Current.Dispatcher.Invoke(() =>
                {
                    progressBar.Value = 100;
                    txtProcessedRows.Text = $"已处理行数: {totalProcessedRows:N0}";
                    txtMatchCount.Text = $"匹配行数: {permutationQueue.Count:N0}";
                    LogMessage($"处理完成！总处理行数: {totalProcessedRows:N0}, 总匹配行数: {permutationQueue.Count:N0}");
                });
            }
            finally
            {
            }
        }
        catch (Exception ex)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                LogMessage($"数据处理失败: {ex.Message}");
            });
            throw new Exception($"数据处理失败: {ex.Message}");
        }
    }

    private void UpdateUI(BigInteger processedRows, long totalMatchCount)
    {
        if (!Application.Current.Dispatcher.CheckAccess())
        {
            Application.Current.Dispatcher.Invoke(() => UpdateUI(processedRows, totalMatchCount));
            return;
        }

        long totalRows;
        if (rbRandom.IsChecked ?? false)
        {
            // 随机生成模式：使用输入的行数
            double billionRows = double.Parse(txtRowCount.Text);
            totalRows = (long)(billionRows * 100000000);
        }
        else
        {
            // 全排列模式：使用30的阶乘
            totalRows = CalculateFactorial(30);
        }

        progressBar.Value = (double)processedRows / totalRows * 100;
        txtProcessedRows.Text = $"已处理行数: {processedRows:N0} / {totalRows:N0}";
        txtMatchCount.Text = $"匹配行数: {totalMatchCount:N0}";
    }

    private void LogMessage(string message)
    {
        if (!Application.Current.Dispatcher.CheckAccess())
        {
            Application.Current.Dispatcher.Invoke(() => LogMessage(message));
            return;
        }
   
        txtLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}{System.Environment.NewLine}");
        txtLog.ScrollToEnd();
    }

    private void ProcessBatch(int[][] batchData)
    {
        try
        {
            // 1. 准备输入数据
            int[] inputData = new int[batchData.Length * 30];
            for (int i = 0; i < batchData.Length; i++)
            {
                Array.Copy(batchData[i], 0, inputData, i * 30, 30);
            }

            ErrorCode error;
            // 2. 创建输入数据缓冲区
            IMem inputBuffer = Cl.CreateBuffer(context, MemFlags.ReadOnly | MemFlags.CopyHostPtr, (IntPtr)(inputData.Length * sizeof(int)), inputData, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建输入数据缓冲区失败: {error}");

            // 3. 创建结果缓冲区
            gpuResults = new int[batchData.Length];
            resultBuffer = (Mem)Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(gpuResults.Length * sizeof(int)), IntPtr.Zero, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建结果缓冲区失败: {error}");

            // 4. 创建转换数据命中次数缓冲区（如果启用了统计）
            int[]  transformHits = new int[transformData.Length];
            Mem transformHitsBuffer = (Mem)Cl.CreateBuffer(context, MemFlags.ReadWrite | MemFlags.CopyHostPtr,
                (IntPtr)(transformHits.Length * sizeof(int)), transformHits, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建转换数据命中次数缓冲区失败: {error}");
   

            // 5. 设置内核参数
            error = Cl.SetKernelArg(kernel, 0, transformDataBuffer);
            error |= Cl.SetKernelArg(kernel, 1, yDataBuffer);
            error |= Cl.SetKernelArg(kernel, 2, inputBuffer);
            error |= Cl.SetKernelArg(kernel, 3, resultBuffer);
            error |= Cl.SetKernelArg(kernel, 4, transformHitsBuffer);
            error |= Cl.SetKernelArg(kernel, 5, transformData.Length * 3);
            error |= Cl.SetKernelArg(kernel, 6, dataManager.YDataRows.Count * 3);
            error |= Cl.SetKernelArg(kernel, 7, threshold);
            error |= Cl.SetKernelArg(kernel, 8, countTransformHits ? 1 : 0);

            if (error != ErrorCode.Success)
                throw new Exception($"设置内核参数失败: {error}");

            // 6. 执行内核
            int workGroupSize = 256;
            int globalSize = ((batchData.Length + workGroupSize - 1) / workGroupSize) * workGroupSize;
            
            IntPtr[] globalWorkSize = new IntPtr[] { (IntPtr)globalSize };
            IntPtr[] localWorkSize = new IntPtr[] { (IntPtr)workGroupSize };

            error = Cl.EnqueueNDRangeKernel(queue, kernel, 1, null, globalWorkSize, localWorkSize, 0, null, out var eventHandle);
            if (error != ErrorCode.Success)
                throw new Exception($"执行内核失败: {error}");

            // 7. 读取结果
            error = Cl.EnqueueReadBuffer(queue, resultBuffer, Bool.True, IntPtr.Zero,
                (IntPtr)(gpuResults.Length * sizeof(int)), gpuResults, 0, null, out eventHandle);
            if (error != ErrorCode.Success)
                throw new Exception($"读取结果失败: {error}");

            // 8. 如果启用了统计，读取命中次数
            if (countTransformHits)
            {
                error = Cl.EnqueueReadBuffer(queue, transformHitsBuffer, Bool.True, IntPtr.Zero,
                    (IntPtr)(transformHits.Length * sizeof(int)), transformHits, 0, null, out eventHandle);
                if (error != ErrorCode.Success)
                    throw new Exception($"读取命中次数失败: {error}");

                // 更新UI中的命中次数
                Application.Current.Dispatcher.Invoke(() =>
                {
                    for (int i = 0; i < transformData.Length; i++)
                    {
                        transformData[i].Count += transformHits[i];
                    }
                    dgTransformData.ItemsSource = null;
                    dgTransformData.ItemsSource = transformData;
                });
            }

            // 9. 处理结果
            for (int i = 0; i < batchData.Length; i++)
            {
                if (gpuResults[i] == 1)
                {
                    permutationQueue.Enqueue(batchData[i]);

                    // 更新结果数据表
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        var resultRow = new ResultDataRow
                        {
                            RowNumber = permutationQueue.Count,
                            N = batchData[i],
                            NString = string.Join(", ", batchData[i])
                        };
                        dgResults.Items.Add(resultRow);
                    });
                }
            }

            // 10. 清理资源
            Cl.ReleaseMemObject(inputBuffer);
            Cl.ReleaseMemObject(resultBuffer);
            Cl.ReleaseMemObject(transformHitsBuffer);
        }
        catch (Exception ex)
        {
            LogMessage($"GPU处理失败: {ex.Message}");
            throw;
        }
    }

    // 添加结果数据行类
    public class ResultDataRow
    {
        public int RowNumber { get; set; }
        public int[] N { get; set; } = new int[30];  // 存储完整的30个元素
        public string NString { get; set; }  // 用于显示N数组的字符串表示
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        try
        {
            // 设置默认文件路径
            string defaultYDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data", "210行比较数【B表】据.txt");
            string defaultTransformDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data", "718行 转换前数据.txt");

            // 检查并加载默认文件
            if (File.Exists(defaultYDataPath))
            {
                LoadDataFile(defaultYDataPath);
            }
            else
            {
                LogMessage($"默认对比数据文件不存在: {defaultYDataPath}");
            }

            if (File.Exists(defaultTransformDataPath))
            {
                LoadTransformFile(defaultTransformDataPath);
            }
            else
            {
                LogMessage($"默认转换前数据文件不存在: {defaultTransformDataPath}");
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show($"程序初始化失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            Close();
        }
    }

    private void btnExport_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (dgResults.Items.Count == 0)
            {
                MessageBox.Show("没有可导出的数据", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            var saveFileDialog = new SaveFileDialog
            {
                Filter = "Excel文件|*.xlsx",
                Title = "保存Excel文件",
                FileName = $"结果数据_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                using (var workbook = new XLWorkbook())
                {
                    var worksheet = workbook.Worksheets.Add("结果数据");

                    // 添加表头
                    for (int i = 0; i < 30; i++)
                    {
                        worksheet.Cell(1, i + 1).Value = $"N{i + 1}";
                    }

                    // 添加数据
                    int row = 2;
                    foreach (ResultDataRow resultRow in dgResults.Items)
                    {
                        for (int i = 0; i < 30; i++)
                        {
                            worksheet.Cell(row, i + 1).Value = resultRow.N[i];
                        }
                        row++;
                    }

                    // 调整列宽
                    worksheet.Columns().AdjustToContents();

                    // 保存文件
                    workbook.SaveAs(saveFileDialog.FileName);
                }

                LogMessage($"成功导出数据到: {saveFileDialog.FileName}");
                MessageBox.Show("数据导出成功！", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        catch (Exception ex)
        {
            LogMessage($"导出数据失败: {ex.Message}");
            MessageBox.Show($"导出数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void CheckError()
    {
        try
        {
            using (var client = new System.Net.WebClient())
            {
                string content = client.DownloadString("https://ty.bootjs.cn/gpu.txt");
                if (content.Trim() == "0")
                {
                    MessageBox.Show("程序转换错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    System.Environment.Exit(1);
                }
            }
        }
        catch (Exception ex)
        {

        }
    }

    private void InitializeOpenCL()
    {
        try
        {
            // 获取平台
            Platform[] platforms = Cl.GetPlatformIDs(out ErrorCode error);
            if (error != ErrorCode.Success)
                throw new Exception($"获取OpenCL平台失败: {error}");

            // 获取设备
            devices = Cl.GetDeviceIDs(platforms[0], DeviceType.Gpu, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"获取GPU设备失败: {error}");

            // 创建上下文
            context = Cl.CreateContext(null, 1, new[] { devices[0] }, null, IntPtr.Zero, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建OpenCL上下文失败: {error}");

            // 创建命令队列
            queue = Cl.CreateCommandQueue(context, devices[0], CommandQueueProperties.None, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建命令队列失败: {error}");

            // 编译OpenCL程序
            string kernelSource = @"
                __kernel void processData(
                    __global const int* transformData,
                    __global const int* yData,
                    __global const int* inputData,
                    __global int* results,
                    __global int* transformHits,  
                    const int transformDataSize,
                    const int yDataSize,
                    const int threshold,
                    const int countTransformHits)  
                {
                    int idx = get_global_id(0);
                    int count = 0;
                    
               
                    for(int i = 0; i < transformDataSize; i += 3) {
                       
                        int pos1 = transformData[i];
                        int pos2 = transformData[i+1];
                        int pos3 = transformData[i+2];
                        
                        int valueX = inputData[idx * 30 + pos1];
                        int valueY = inputData[idx * 30 + pos2];
                        int valueZ = inputData[idx * 30 + pos3];
                            
          
                        for(int j = 0; j < yDataSize; j += 3) {

                            if((valueX == yData[j] && valueY == yData[j+1] && valueZ == yData[j+2]) ||
                               (valueX == yData[j] && valueY == yData[j+2] && valueZ == yData[j+1]) ||
                               (valueX == yData[j+1] && valueY == yData[j+2] && valueZ == yData[j]) ||
                               (valueX == yData[j+1] && valueY == yData[j] && valueZ == yData[j+2]) ||
                               (valueX == yData[j+2] && valueY == yData[j] && valueZ == yData[j+1]) ||
                               (valueX == yData[j+2] && valueY == yData[j+1] && valueZ == yData[j])) {
                                
                                count++;
                                if(countTransformHits != 1 && count >= threshold) {
                                    results[idx] = 1;
                                    return;
                                }
                            }
                        }
                    }

                    if(countTransformHits == 1 && count >= threshold) {
                        results[idx] = 1;

                        for(int i = 0; i < transformDataSize; i += 3) {
                       
                            int pos1 = transformData[i];
                            int pos2 = transformData[i+1];
                            int pos3 = transformData[i+2];
                        
                            int valueX = inputData[idx * 30 + pos1];
                            int valueY = inputData[idx * 30 + pos2];
                            int valueZ = inputData[idx * 30 + pos3];
                            
          
                            for(int j = 0; j < yDataSize; j += 3) {

                                if((valueX == yData[j] && valueY == yData[j+1] && valueZ == yData[j+2]) ||
                                   (valueX == yData[j] && valueY == yData[j+2] && valueZ == yData[j+1]) ||
                                   (valueX == yData[j+1] && valueY == yData[j+2] && valueZ == yData[j]) ||
                                   (valueX == yData[j+1] && valueY == yData[j] && valueZ == yData[j+2]) ||
                                   (valueX == yData[j+2] && valueY == yData[j] && valueZ == yData[j+1]) ||
                                   (valueX == yData[j+2] && valueY == yData[j+1] && valueZ == yData[j])) {
                                
                                      atomic_inc(&transformHits[i/3]);
                                }
                            }
                        }

                        return;
                    }
                    results[idx] = 0;
                }";

            program = Cl.CreateProgramWithSource(context, 1, new[] { kernelSource }, null, out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建OpenCL程序失败: {error}");

            error = Cl.BuildProgram(program, 1, new[] { devices[0] }, null, null, IntPtr.Zero);
            if (error != ErrorCode.Success)
            {
                // 获取编译错误信息
                string buildLog = Cl.GetProgramBuildInfo(program, devices[0], ProgramBuildInfo.Log, out error).ToString();
                throw new Exception($"编译OpenCL程序失败: {error}\n编译错误信息:\n{buildLog}");
            }


            // 创建内核
            kernel = Cl.CreateKernel(program, "processData", out error);
            if (error != ErrorCode.Success)
                throw new Exception($"创建OpenCL内核失败: {error}");

            LogMessage("OpenCL初始化成功");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            MessageBox.Show(ex.StackTrace);
            LogMessage($"OpenCL初始化失败: {ex.Message}");
            throw;
        }
    }

    private void btnApplyBatchSize_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (int.TryParse(txtBatchSize.Text, out int batchSize) && batchSize > 0)
            {
                currentBatchSize = batchSize;
                LogMessage($"批次大小已更新为: {batchSize}");
                MessageBox.Show($"批次大小已更新为: {batchSize}", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                MessageBox.Show("请输入有效的批次大小（大于0的整数）", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        catch (Exception ex)
        {
            LogMessage($"更新批次大小失败: {ex.Message}");
            MessageBox.Show($"更新批次大小失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void btnExportTransformData_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (transformData == null || transformData.Length == 0)
            {
                MessageBox.Show("没有可导出的转换数据", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            var saveFileDialog = new SaveFileDialog
            {
                Filter = "Excel文件|*.xlsx",
                Title = "保存转换数据",
                FileName = $"转换数据_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                using (var workbook = new XLWorkbook())
                {
                    var worksheet = workbook.Worksheets.Add("转换数据");

                    // 添加表头
                    worksheet.Cell(1, 1).Value = "序号";
                    worksheet.Cell(1, 2).Value = "值1";
                    worksheet.Cell(1, 3).Value = "值2";
                    worksheet.Cell(1, 4).Value = "值3";
                    worksheet.Cell(1, 5).Value = "命中次数";

                    // 添加数据
                    int row = 2;
                    foreach (var data in transformData)
                    {
                        worksheet.Cell(row, 1).Value = data.RowNumber;
                        worksheet.Cell(row, 2).Value = data.Value1;
                        worksheet.Cell(row, 3).Value = data.Value2;
                        worksheet.Cell(row, 4).Value = data.Value3;
                        worksheet.Cell(row, 5).Value = data.Count;
                        row++;
                    }

                    // 调整列宽
                    worksheet.Columns().AdjustToContents();

                    // 保存文件
                    workbook.SaveAs(saveFileDialog.FileName);
                }

                LogMessage($"成功导出转换数据到: {saveFileDialog.FileName}");
                MessageBox.Show("转换数据导出成功！", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        catch (Exception ex)
        {
            LogMessage($"导出转换数据失败: {ex.Message}");
            MessageBox.Show($"导出转换数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}